﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Data.SqlClient;
using System.Web.Services.Protocols;
using System.Configuration;
using DataModels;
using ServiceUtilities;
using System.Runtime.Serialization;

[WebService(Namespace = "http://localhost/MainService")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
[System.Web.Script.Services.ScriptService]

public class Service : System.Web.Services.WebService
{
    public Service () {

        //Uncomment the following line if using designed components 
        //InitializeComponent(); 
    }

    #region Party Hosting methods
    /*---------------------------------------------------------------------------------*\
     * Methods used by the desktop application so the host can control the party.
     * The user needs to be authenticated for all of these.
     * 
     * Iteration 1 Goals for Party Control:
     *  - Create a party (with no settings options)
     *  - Add/remove songs to/from playlist
     *  - Get the next song in the queue (this updates the queue)
     *  - Update the Now Playing song
    \*---------------------------------------------------------------------------------*/

    // The following two fields will most likely be removed once sessions are deprecated
    private string AuthenticatedID
    {
        get { return (string)Session["AuthenticatedHostID"]; }
        set { Session["AuthenticatedHostID"] = value; }
    }

    private string HostPartyID
    {
        get { return (string)Session["HostPartyID"]; }
        set { Session["HostPartyID"] = value; }
    }

    /// <summary>
    /// Begins a new session on the server and authenticates the user as a party host.
    /// </summary>
    /// <returns>returns true if the user is authenticated successfully</returns>
    [WebMethod(EnableSession=true)]
    public bool BeginHostSession(string facebookId)
    {        
        //Start a new session if there already was one.
        if (!Session.IsNewSession)
            Session.Clear();

        //TODO:
        //  1. Authenticate a signed request using our app_secret
        //  2. Get the userId from the facebookSignedRequest instead of as a string argument
        //      (This can be done using the .NET Facebook API implementation.)

        AuthenticatedID = facebookId;
        return true;
    }



    /// <summary>
    /// Creates a party in the database and returns the party code.
    /// Requires that the user has authenticated.
    /// 
    /// TODO: Party privacy and settings. Future Iteration
    /// </summary>
    /// <returns>
    /// returns the new party's partyid the application should use to identify it
    /// with theserver and the party access code that party host will give to his
    /// or her guests.
    /// </returns>
    [WebMethod(EnableSession = true)]
    public CreatePartyData CreateParty(string description, string accessCode, int accessLevel, int votesPerUser, int voteReplenish, bool allowsRequests)
    {
        try
        {
            return ServiceUtilities.ServiceUtilities.CreateParty(ConfigurationManager.ConnectionStrings["NextrackConn"].ConnectionString, description, accessCode, accessLevel, votesPerUser, voteReplenish, allowsRequests);
        }
        catch (Exception ex)
        {
            throw new SoapException(ex.Message, new System.Xml.XmlQualifiedName());
        }
    }

    /// <summary>
    /// Destroys an existing party
    /// 
    /// </summary>
    /// <returns>
    /// </returns>
    [WebMethod(EnableSession = true)]
    public bool DestroyParty(string partyID)
    {
        try
        {
            return ServiceUtilities.ServiceUtilities.DestroyParty(ConfigurationManager.ConnectionStrings["NextrackConn"].ConnectionString, partyID);
        }
        catch (Exception ex)
        {
            throw new SoapException(ex.Message, new System.Xml.XmlQualifiedName());
        }
    }

    /// <summary>
    /// Add a song to this party's playlist by adding it to Songs
    /// Requires a host session
    /// </summary>
    /// <param name="artist">Artist</param>
    /// <param name="album">Album</param>
    /// <param name="title">Song title</param>
    /// <param name="partyID">Party ID to add song to</param>
    /// <returns>ID of newly created song</returns>
    [WebMethod(EnableSession = true)]
    public string AddSong(string partyID, string artist, string album, string title)
    {
        return ServiceUtilities.ServiceUtilities.AddSong(ConfigurationManager.ConnectionStrings["NextrackConn"].ConnectionString, partyID, artist, album, title);
    }

    /// <summary>
    /// Remove a song from the song library and queues
    /// </summary>
    /// <param name="partyID">Current party ID</param>
    /// <param name="songID">Song to remove</param>
    /// <returns>Returns true if successful</returns>
    [WebMethod(EnableSession = true)]
    public bool RemoveSong(string partyID, string songID)
    {
        return ServiceUtilities.ServiceUtilities.RemoveSong(ConfigurationManager.ConnectionStrings["NextrackConn"].ConnectionString, partyID, songID);
    }

    /// <summary>
    /// Called by the desktop to update the now-playing song
    /// </summary>
    /// <param name="songID">Song ID to set now playing</param>
    [WebMethod(EnableSession=true)]
    public bool UpdateNowPlaying(string partyID, string songID)
    {
        try
        {
            return ServiceUtilities.ServiceUtilities.UpdateNowPlaying(ConfigurationManager.ConnectionStrings["NextrackConn"].ConnectionString, partyID, songID);
        }
        catch (Exception ex)
        {
            throw new SoapException(ex.Message, new System.Xml.XmlQualifiedName());
        }
    }

    //---------------------------------------------------------------------------------//
    #endregion


    #region Data Retrieval Methods
    /*---------------------------------------------------------------------------------*\
     * Methods used by the desktop application and also the mobile application
     * No authentication is necessary.
    \*---------------------------------------------------------------------------------*/

    /// <summary>
    /// Call to upvote a song
    /// </summary>
    /// <param name="partyID">Current party ID</param>
    /// <param name="songID">Song to upvote</param>
    /// <returns>Does queue need to be updated</returns>
    [WebMethod]
    public bool UpvoteSong(string partyID, string songID)
    {
        return ServiceUtilities.ServiceUtilities.UpvoteSong(ConfigurationManager.ConnectionStrings["NextrackConn"].ConnectionString, partyID, songID);
    }

    /// <summary>
    /// Call to downvote song
    /// </summary>
    /// <param name="partyID">Current party ID</param>
    /// <param name="songID">Song ID to downvote</param>
    /// <returns>Does queue need to be updated</returns>
    [WebMethod]
    public bool DownvoteSong(string partyID, string songID)
    {
        return ServiceUtilities.ServiceUtilities.DownvoteSong(ConfigurationManager.ConnectionStrings["NextrackConn"].ConnectionString, partyID, songID);
    }

    /// <summary>
    /// Returns the current data of the song that is playing
    /// </summary>
    /// <param name="partyID">ID of the party</param>
    /// <returns>Song data of the song currently playing</returns>
    [WebMethod]
    public SongData GetNowPlaying(string partyID)
    {
        return ServiceUtilities.ServiceUtilities.GetNowPlaying(ConfigurationManager.ConnectionStrings["NextrackConn"].ConnectionString, partyID);
    }

    /// <summary>
    /// Gets queue data for a given party
    /// </summary>
    /// <param name="partyID">ID of party</param>
    /// <returns>List of queue data</returns>
    [WebMethod]
    public List<QueueData> GetQueue(string partyID)
    {
        try
        {
            return ServiceUtilities.ServiceUtilities.GetQueue(ConfigurationManager.ConnectionStrings["NextrackConn"].ConnectionString, partyID);
        }
        catch (Exception ex)
        {
            throw new SoapException(ex.Message, new System.Xml.XmlQualifiedName("GetQueueException"));
        }
    }

    /// <summary>
    /// Returns the last time the queue was changed
    /// </summary>
    /// <param name="partyID"></param>
    /// <returns></returns>
    [WebMethod]
    public DateTime GetLastQueueChange(string partyID)
    {
        return ServiceUtilities.ServiceUtilities.GetLastQueueChange(ConfigurationManager.ConnectionStrings["NextrackConn"].ConnectionString, partyID);
    }

    /// <summary>
    /// Returns a list of all songs in the party database
    /// </summary>
    /// <param name="partyID"></param>
    /// <returns></returns>
    [WebMethod]
    public List<SongData> GetAllSongs(string partyID)
    {
        return ServiceUtilities.ServiceUtilities.GetAllSongs(ConfigurationManager.ConnectionStrings["NextrackConn"].ConnectionString, partyID);
    }

    #endregion
}
